﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace HtmlExtractor
{

    /// <summary>
    /// Allows iteration through a collection in reverse order
    /// </summary>


    internal class ReverseCollection : ICollection
    {
        // Constructor
        public ReverseCollection(ICollection collection)
        {
            _objectCollection = new object[collection.Count];
            collection.CopyTo(_objectCollection, 0);
        }

        #region ICollection

        public int Count
        {
            get { return _objectCollection.Length; }
        }

        public void CopyTo(Array array, int index)
        {
            _objectCollection.CopyTo(array, index);
        }

        public bool IsSynchronized
        {
            get { return false; }
        }

        public object SyncRoot
        {
            get { return null; }
        }

        #endregion

        #region IEnumerable

        public IEnumerator GetEnumerator()
        {
            return new ReverseEnumerator(_objectCollection);
        }

        #endregion

        #region IEnumerator

        public class ReverseEnumerator : IEnumerator
        {
            public ReverseEnumerator(object[] objectCollection)
            {
                // Don't construct if objectCollection is null, since enumeration depends on non-null array for indexing
                if (objectCollection == null) throw new ArgumentNullException();
                _objectCollection = objectCollection;
                Reset();
            }

            #region IEnumerator

            public object Current
            {
                get
                {
                    // If the enumerator points to an element, return it
                    if ((_position < 0) || (_position > _objectCollection.Length - 1)) throw new InvalidOperationException();
                    return _objectCollection[_position];
                }
            }

            public bool MoveNext()
            {
                // Move enumerator to previous element
                return (--_position >= 0);
            }

            public void Reset()
            {
                // Move enumerator to the end of the collection, after the last element
                _position = _objectCollection.Length;
            }

            #endregion

            int _position;
            object[] _objectCollection;
        }

        #endregion

        private object[] _objectCollection;
    }
}
